/*
 * pladc.h
 *
 *  Created on: May 2, 2017
 *      Author: yuanjianen
 */

#ifndef _PLADC_H_
#define _PLADC_H_

#include "typedef.h"
#include "pladc_config.h"

#define INVALID_ADC_CHANNEL  (0xFFU)
#define INVALID_AD_CONFIG_INDEX (0xFFU)
#define INVALID_AD_COEF pladc_define_filter_coeff(0)

//TODO, ml, class5, check all AD bit-depend code
#define ADC_RESOLUTION_BIT (10U)
#define ADC_REF_VOLT       (5U) /*5v voltage*/
#define ZERO_CONFIG_ADC() {INVALID_ADC_CHANNEL, 0U, INVALID_AD_CONFIG_INDEX, INVALID_AD_COEF, 1U, 1U, 0U, NULL, NULL}
#define pladc_define_internal_voltage(physical_volt) (uint16)(((physical_volt)* (1U << ADC_RESOLUTION_BIT)) / 5U)
#define pladc_define_filter_coeff(coeff) (uint8)((coeff) * 256)
#define pladc_convert_internal_to_Q10(internal_voltage)  ((uint16)(((uint32)(internal_voltage) * 10U) * 5U / (1U << ADC_RESOLUTION_BIT))) /*convert LSB from 5/1024 to 1/10*/
#define pladc_convert_internal_to_Q25(internal_voltage)  ((uint16)(((uint32)(internal_voltage) * 25U) * 5U / (1U << ADC_RESOLUTION_BIT))) /*convert LSB from 5/1024 to 1/10*/

typedef struct {
	uint16 ad_raw;
	uint16 ad_5vadj;
	uint16 ad_filtered;
	uint16 ad_mapped; /*map to its physical value with gain and offset!!*/
} PladcData;


typedef void (*PlAdcConverterCallback)(uint8 config_index, PladcData * adc_data);

typedef struct {
	uint16 ad_channel;
	uint16 sample_period_ms;

	uint8 ref_5v_power_index;
	uint8 first_order_coeff;

	uint16 gain_numerator;
	uint16 gain_denominator;
	uint16 offset; /**/

	PlAdcConverterCallback callback;

	uint8* config_index_ref;
} PladcConfig;

extern const PladcConfig pladc_config[];
extern const uint8 pladc_config_count;
extern PladcData pladc_adc_data[];
extern uint16 pladc_device_value[];


#define pladc_read_raw(funid)          (pladc_adc_data[funid].ad_raw)
#define pladc_read_5vadj(funid)        (pladc_adc_data[funid].ad_5vadj)
#define pladc_read_filtered(funid)     (pladc_adc_data[funid].ad_filtered)
#define pladc_read_mapped(funid)       (pladc_adc_data[funid].ad_mapped)

extern void pladc_init_adc(void);
extern void pladc_sample_task(void);
extern void pladc_sample_adc(uint8 config_index);
extern uint16 pladc_get_value_from_device(uint16 channel);
#endif /* _PLADC_H_ */
